<template>
    <div class="consult">
      <el-row>
        <el-col :span="4">
          <el-card class="box-card" :style="{ height: heightCard }">
            <div slot="header" class="clearfix">
              <span
                style="display: inline-block; font-size: 20px; font-weight: bold"
                >标签分组</span
              >
              <el-button
                style="float: right; padding: 3px 0"
                type="text"
                @click="addTagGroup(1)"
                >新增</el-button
              >
            </div>
            <div class="tagGroup">
              <ul
                v-for="(group, index) in tagGroups"
                :key="index"
                @click="handleGroupClick(group, index)"
              >
                <li :class="{ active: index === selectedGroupIndex }">
                  {{ group.tagName }}
                  <el-button
                    style="float: right; padding: 3px 0"
                    type="text"
                    @click="groupDel(group, 1)"
                    >删除</el-button
                  >
                  <el-button
                    style="float: right; padding: 3px 0"
                    type="text"
                    @click="groupUpdate(1, group)"
                    >修改</el-button
                  >
                </li>
              </ul>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card class="box-card" :style="{ height: heightCard }">
            <div slot="header" class="clearfix">
              <span
                style="display: inline-block; font-size: 20px; font-weight: bold"
                >标签分类</span
              >
              <el-button
                style="float: right; padding: 3px 0"
                type="text"
                @click="addTagGroup(2)"
                >新增</el-button
              >
            </div>
            <div class="tagGroup">
              <ul
                v-for="(category, categoryIndex) in categories"
                :key="categoryIndex"
                @click="handleCategoryClick(categories, categoryIndex)"
              >
                <li :class="{ active: categoryIndex === selectedCategoryIndex }">
                  {{ category.tagName }}
                  <el-button
                    style="float: right; padding: 3px 0"
                    type="text"
                    @click="groupDel(category, 2)"
                    >删除</el-button
                  >
                  <el-button
                    style="float: right; padding: 3px 0"
                    type="text"
                    @click="groupUpdate(2, category)"
                    >修改</el-button
                  >
                </li>
              </ul>
            </div>
          </el-card>
        </el-col>
        <el-col :span="4">
          <el-card class="box-card" :style="{ height: heightCard }">
            <div slot="header" class="clearfix">
              <span
                style="display: inline-block; font-size: 20px; font-weight: bold"
                >标签定义</span
              >
              <el-button
                style="float: right; padding: 3px 0"
                type="text"
                @click="addTagGroup(3)"
                >新增</el-button
              >
            </div>
            <div class="tagGroup">
              <ul
                v-for="(tags, tagsIndex) in tags"
                :key="tagsIndex"
                @click="handleTagClick(tags, tagsIndex)"
              >
                <li :class="{ active: tagsIndex === selectTagsIndex }">
                  {{ tags.tagName }}
                  <el-button
                    style="float: right; padding: 3px 0"
                    type="text"
                    @click="tagRequirementDelete(tags)"
                    >删除</el-button
                  >
                  <el-button
                    style="float: right; padding: 3px 0"
                    type="text"
                    @click="groupUpdate(3, tags)"
                    >修改</el-button
                  >
                </li>
              </ul>
            </div>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card class="box-card" :style="{ height: heightCard }">
            <div style="display: flex; justify-content: end; padding: 10px">
              <el-button
                type="primary"
                size="medium"
                plain
                @click="handleClickTableAdd"
                >新增</el-button
              >
              <el-button type="danger" size="medium" plain @click="tableDel"
                >删除</el-button
              >
            </div>
            <div
              style="
                display: flex;
                justify-content: space-between;
                align-items: center;
                margin: 20px 20px 0 20px;
              "
            >
              <h4>条件定义:</h4>
              <span style="color: red">多个比较值使用|分割</span>
            </div>
            <div style="padding: 0 20px 0 20px">
              <vxe-table
                border
                ref="xTable"
                :resizable="true"
                :align="allAlign"
                :data="tableData"
                :height="heightTable"
                :scroll-y="{ enabled: false }"
                highlight-current-row
                @current-change="handleCurrentRow"
              >
                <!-- show-overflow -->
                <vxe-column width="60" align="center">
                  <template #default>
                    <span class="drag-btn">
                      <i class="vxe-icon--menu"></i>
                    </span>
                  </template>
                </vxe-column>
                <vxe-column title="序号" type="seq" width="60"></vxe-column>
                <vxe-column title="表名" field="tabName">
                  <template slot-scope="scope">
                    <el-select
                      @change="tableNameChang(scope.row, $event)"
                      ref="produceRef"
                      v-model="scope.row.tabName"
                      placeholder="请选择"
                      clearable
                    >
                      <el-option
                        v-for="item in nameOption"
                        :key="item.tableName"
                        :label="item.tableShowName"
                        :value="item.tableName"
                      >
                      </el-option>
                    </el-select>
                  </template>
                </vxe-column>
                <vxe-column title="字段" field="tagField">
                  <template slot-scope="scope">
                    <tagOperatorField
                      v-model="scope.row.tagField"
                      :row="scope.row"
                    />
                    <!-- <el-select
                      @change="fieldChange(scope.row, $event)"
                      v-model="scope.row.tagField"
                      placeholder="请选择"
                      clearable
                    >
                      <el-option
                        v-for="item in fieldOptions"
                        :key="item.fieldName"
                        :label="item.fieldShowName"
                        :value="item.fieldName"
                      >
                      </el-option>
                    </el-select> -->
                  </template>
                </vxe-column>
                <!-- tagOperatorField这个子节点没有显示是什么原因 -->
                <vxe-column title="比较符" field="tagOperator">
                  <template slot-scope="scope">
                    <el-select
                      @change="$forceUpdate()"
                      v-model="scope.row.tagOperator"
                      placeholder="请选择"
                      clearable
                    >
                      <el-option
                        v-for="item in comparisonOptions"
                        :key="item.CODE"
                        :label="item.NAME"
                        :value="item.CODE"
                      >
                      </el-option>
                    </el-select>
                  </template>
                </vxe-column>
                <vxe-column field="tagCondition" title="比较值">
                  <template slot-scope="scope">
                    <custum-type
                      v-model="scope.row.tagCondition"
                      :row="scope.row"
                    />
                  </template>
                </vxe-column>
              </vxe-table>
            </div>
            <div
              style="
                display: flex;
                justify-content: center;
                align-items: center;
                margin-top: 60px;
              "
            >
              查询条件运算方式：<el-input
                size="medium"
                v-model="searchOperate"
                style="width: 500px"
                @change="inputValue"
              />
              <!-- @change="handleInputQuery" -->
            </div>
            <p style="color: red; display: flex; justify-content: center">
              编写条件定义的运算逻辑。如:同时满足条件1和2，然后在满足条件3，输入框填写<br />(1+2)+3
            </p>
            <div style="display: flex; justify-content: end; margin-right: 30px">
              <el-button
                type="primary"
                size="medium"
                @click="onSubmitInput"
                :disabled="isButtonDisabled"
                >保存</el-button
              >
            </div>
          </el-card>
        </el-col>
      </el-row>
      <tagAddDialog
        ref="tagAddDialogRefs"
        v-if="tagAddDialogFlag"
        @initData="getConsultList"
        @on-group-add-success="handleGroupAddSuccess"
      />
      <tagUpdateDialogFrist
        ref="tagUpdateDialogFristRefs"
        v-if="tagUpdateDialogFristFlag"
        @initData="getConsultList"
        @on-group-add-success="handleGroupAddSuccess"
      />
      <tagButtonClickEvent
        ref="tagButtonClickEventRefs"
        :list="tableData"
        @addData="handleClickTableAdd"
        v-if="tagButtonClickEventFlag"
      />
    </div>
  </template>
    
    <script>
  import tagAddDialog from "./componentsConsult/tagAddDialogFrist.vue";
  import tagUpdateDialogFrist from "./componentsConsult/tagUpdateDialogFrist";
  import tagButtonClickEvent from "./componentsConsult/tagButtonClickEvent.vue";
  import CustumType from "./componentsConsult/custumType.vue";
  import tagOperatorField from "./componentsConsult/tagOperatorField.vue";
  import Sortable from "sortablejs";
  import {
    consultList,
    tagDefineDelete,
    tagOperationQuery,
    queryDict,
    tagTableAndColumnConfigList,
    tagRequirementList,
    saveTagRequirementEdit,
    tagRequirementDelete,
  } from "@/api/students/organization/consult";
  import store from "@/store";
  export default {
    components: {
      tagAddDialog,
      tagUpdateDialogFrist,
      tagButtonClickEvent,
      CustumType,
      tagOperatorField,
    },
    data() {
      return {
        heightCard: window.innerHeight - 125 + "px",
        heightTable: window.innerHeight - 450 + "px",
        tagGroups: [],
        categories: [],
        tags: [],
        categories: null,
        groupData: null,
        tagsRow: null,
        allAlign: "center",
        tableData: [],
        nameOption: [],
        fieldOptions: [],
        comparisonOptions: [],
        selectedGroupIndex: 0,
        selectedCategoryIndex: 0,
        selectTagsIndex: 0,
        tagAddDialogFlag: false,
        tagUpdateDialogFristFlag: false,
        tagButtonClickEventFlag: false,
        currentRow: null,
        searchOperate: "",
        value1: "",
        num: "",
        textarea: "",
        inputId: "",
        inputTagDefineId: "",
        inputTagFormula: "",
        tagsClickList: null,
        fieldValues: "",
        typeTagCondition: "",
        tagConditionOption: [], //比较符数组
        isButtonDisabled: false, // 按钮是否被禁用
        timer: null, // 定时器变量
      };
    },
    computed: {
      currentGroup() {
        return this.tagGroups[this.selectedGroupIndex];
      },
      currentCategory() {
        return this.currentGroup.categories[this.selectedCategoryIndex]; // 默认显示第一个分类
      },
    },
    created() {
      this.rowDrop();
      this.getConsultList();
      this.queryDict();
      this.tableNameList();
    },
    beforeDestroy() {
      if (this.sortable) {
        this.sortable.destroy();
      }
    },
    methods: {
      // 条件定义的新增
      handleClickTableAdd(newData) {
        this.tagButtonClickEventFlag = true;
        this.$nextTick(() => {
          this.$refs.tagButtonClickEventRefs.init();
        });
        this.tableData.push(newData);
      },
      tableNameChang(row, value) {
        // console.log(row,"row");
        this.$forceUpdate();
      },
      fieldChange(row, value) {
        this.$forceUpdate();
      },
      // 表名
      tableNameList() {
        const params = {
          userId: store.getters.user_id.toString(),
          userName: store.getters.userName.toString(),
          token: store.getters.token.toString(),
          type: "1",
        };
        tagTableAndColumnConfigList(params).then((res) => {
          this.nameOption = res.resultdata;
        });
      },
      // 字段
      // fieldList(tableNameValue) {
      //   const params = {
      //     userId: store.getters.user_id.toString(),
      //     userName: store.getters.userName.toString(),
      //     token: store.getters.token.toString(),
      //     type: "2",
      //     // 需要传tableNameList中的表名
      //     tableName: tableNameValue,
      //   };
      //   tagTableAndColumnConfigList(params).then((res) => {
      //     this.fieldOptions = res.resultdata;
      //   });
      // },
      // 比较符
      queryDict() {
        const params = {
          userId: store.getters.user_id.toString(),
          userName: store.getters.userName.toString(),
          token: store.getters.token.toString(),
        };
        queryDict(params).then((res) => {
          this.comparisonOptions = res.resultdata;
        });
      },
      // 默认展示的数据
      getConsultList() {
        const params = {
          userId: store.getters.user_id.toString(),
          userName: store.getters.userName.toString(),
          token: store.getters.token.toString(),
          parentId: "-1",
          tagType: "1",
        };
        consultList(params).then((result) => {
          this.tagGroups = result.resultdata.data;
          if (this.tagGroups.length > 0) {
            this.handleGroupClick(this.tagGroups[0], 0); // 获取第一条标签分组数据
          }
        });
      },
      // 点击标签分组
      handleGroupClick(groupData, index) {
        this.groupData = groupData;
        const params = {
          userId: store.getters.user_id.toString(),
          userName: store.getters.userName.toString(),
          token: store.getters.token.toString(),
          parentId: this.groupData.id,
          tagType: "2",
        };
        consultList(params).then((result) => {
          this.categories = result.resultdata.data;
          if (this.categories.length > 0) {
            this.handleCategoryClick(this.categories, 0); // 获取第一个标签分类数据并展示第一个标签定义数据
          } else {
            // 清空标签分类和标签定义数据
            this.categories = [];
            this.tags = [];
          }
        });
        this.selectedGroupIndex = index;
        this.selectedCategoryIndex = 0; // 将标签分类下标设置为0
        this.selectTagsIndex = 0; // 将标签定义下标设置为0
      },
      // 点击标签分类
      handleCategoryClick(categories, categoryIndex) {
        this.categories = categories;
        const params = {
          userId: store.getters.user_id.toString(),
          userName: store.getters.userName.toString(),
          token: store.getters.token.toString(),
          parentId: this.categories[categoryIndex].id,
          tagType: "3",
        };
        consultList(params).then((result) => {
          this.tags = result.resultdata.data;
          if (this.tags.length > 0) {
            this.handleTagClick(this.tags[0], 0); // 展示第一条标签定义数据
          }
        });
        this.selectedCategoryIndex = categoryIndex;
      },
      // 点击标签定义
      handleTagClick(tags, tagsIndex) {
        this.tagsClickList = tags;
        this.selectTagsIndex = tagsIndex;
        this.getTableList();
      },
      // 新增
      addTagGroup(type) {
        this.tagAddDialogFlag = true;
        this.$nextTick(() => {
          this.$refs.tagAddDialogRefs.init(
            type,
            this.groupData,
            this.categories,
            this.selectedGroupIndex,
            this.selectedCategoryIndex
          );
        });
      },
      // 修改
      groupUpdate(type, data) {
        this.tagUpdateDialogFristFlag = true;
        this.$nextTick(() => {
          this.$refs.tagUpdateDialogFristRefs.init(
            type,
            data,
            this.groupData,
            this.categories,
            this.selectedGroupIndex,
            this.selectedCategoryIndex
          );
        });
      },
      // 获取表格数据
      getTableList() {
        const params = {
          userId: store.getters.user_id.toString(),
          userName: store.getters.userName.toString(),
          token: store.getters.token.toString(),
          tagDefineId: this.tagsClickList.id,
        };
        tagRequirementList(params).then((result) => {
          this.tableData = result.resultdata.data; //表格
          this.inputId = result.resultdata.tagOperation.id;
          this.searchOperate = result.resultdata.tagOperation.tagFormula;
        });
      },
      // 删除
      groupDel(group, type) {
        this.$confirm("确定删除当前行?", "操作提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(() => {
          const params = {
            userId: store.getters.user_id.toString(),
            userName: store.getters.userName.toString(),
            token: store.getters.token.toString(),
            id: group.id,
            type: type,
          };
          tagDefineDelete(params).then((response) => {
            if (response.result) {
              this.$message({
                type: "success",
                message: response.resultdata,
              });
              this.getConsultList();
            } else {
              this.$message({
                type: "error",
                message: response.resultdata,
              });
            }
          });
        });
      },
      // 表格删除
      tableDel() {
        if (this.currentRow !== null) {
          this.$confirm("确定删除当前行?", "操作提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          }).then(() => {
            const params = {
              userId: store.getters.user_id.toString(),
              userName: store.getters.userName.toString(),
              token: store.getters.token.toString(),
              id: this.currentRow.id,
            };
            tagRequirementDelete(params).then((response) => {
              if (response.result) {
                this.$message({
                  type: "success",
                  message: response.resultdata,
                });
                this.getConsultList();
              } else {
                this.$message({
                  type: "error",
                  message: response.resultdata,
                });
              }
            });
          });
        } else {
          this.$message({
            type: "warning",
            message: "请勾选一条数据",
          });
        }
      },
      // 运算方式的删除
      tagRequirementDelete(tag) {
        this.$confirm("确定删除当前行?", "操作提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(() => {
          const params = {
            userId: store.getters.user_id.toString(),
            userName: store.getters.userName.toString(),
            token: store.getters.token.toString(),
            id: tag.id,
            tagDefineId: tag.id,
            all: "1",
            type: "3",
          };
          tagRequirementDelete(params).then((response) => {
            if (response.result == true) {
              this.$message({
                type: "success",
                message: response.resultdata,
              });
              this.getConsultList();
            } else {
              this.$message({
                type: "error",
                message: response.resultdata,
              });
            }
          });
        });
      },
      handleCurrentRow(currentRow) {
        this.currentRow = currentRow.row;
      },
  
      // input进行搜索
      // handleInputQuery() {
      //   const params = {
      //     userId: store.getters.user_id.toString(),
      //     userName: store.getters.userName.toString(),
      //     token: store.getters.token.toString(),
      //     // id:"",
      //     // tagDefineId:"",
      //     tagFormula: this.searchOperate,
      //   };
      //   tagOperationQuery(params).then((res) => {});
      // },
  
      // input框的保存和修改
      onSubmitInput() {
        this.isButtonDisabled = true; // 点击时立即禁用按钮
        const params = {
          userId: store.getters.user_id.toString(),
          userName: store.getters.userName.toString(),
          token: store.getters.token.toString(),
          tagDefineId: this.tagsClickList.id,
          list: [],
          tagOperation: {
            id: this.inputId,
            tagFormula: this.searchOperate,
          },
        };
        this.tableData.forEach((item) => {
          const listItem = {
            tagSort: item.tagSort,
            tabName: item.tabName,
            tagField: item.tagField,
            tagOperator: item.tagOperator,
            tagCondition: item.tagCondition,
          };
          params.list.push(listItem); // 将当前行数据添加到list数组中
        });
        saveTagRequirementEdit(params).then((res) => {
          if (res.result) {
            this.$message({
              message: "操作成功",
              type: "success",
            });
            this.getTableList();
          }
          this.timer = setTimeout(() => {
            this.isButtonDisabled = false; // 启用按钮
            clearTimeout(this.timer); // 清除定时器
          }, 2000);
        });
      },
      inputValue() {
        //验证公式合法性
        if (this.formulaJudge(this.searchOperate)) {
          let rowIndex = this.searchOperate.replace(/[^0-9]/gi, "");
          let points = rowIndex.split("");
          points.sort(function (a, b) {
            return b - a;
          });
          if (points[0] > this.tableData.length) {
            this.$message.warning(
              "运算公式中的最大值超过条件个数，请检查后重试！"
            );
            return;
          }
        } else {
          this.$message.warning("运算公式不合法，请检查后重试！");
          return;
        }
      },
  
      //验证公式合法性
      formulaJudge(string) {
        //去除左边及右边的括号（这个是我的公式里面有特殊字符）
        let str = string.replace("{", "").replace("}", "");
        // 剔除空白符
        string = str.replace(/\s/g, "");
        // 错误情况，空字符串
        if ("" === string) {
          return false;
        }
        // 检查数字是否重复出现
        if (/(\d).*\1/.test(string)) {
          return false;
        }
        // 包含非法字符（只允许数字、+、-、(、)，括号为英文括号）
        if (!/^[\d\+\-\(\)]+$/.test(string)) {
          return false;
        }
        // 错误情况，运算符连续
        if (/[\+\-\*\/]{2,}/.test(string)) {
          return false;
        }
        // 空括号
        if (/\(\)/.test(string)) {
          return false;
        }
        // 最后一个符号是加、减、乘、除符号
        if (/[\+\-\*\/]$/.test(string)) {
          return false;
        }
        // 错误情况，括号不配对
        let stack = [];
        for (let i = 0, item; i < string.length; i++) {
          item = string.charAt(i);
          if ("(" === item) {
            stack.push("(");
          } else if (")" === item) {
            if (stack.length > 0) {
              stack.pop();
            } else {
              return false;
            }
          }
        }
        if (0 !== stack.length) {
          return false;
        }
        // 错误情况，(后面是运算符
        if (/\([\+\-\*\/]/.test(string)) {
          return false;
        }
        // 错误情况，)前面是运算符
        if (/[\+\-\*\/]\)/.test(string)) {
          return false;
        }
        // 错误情况，(前面不是运算符
        if (/[^\+\-\*\/\(]\(/.test(string)) {
          return false;
        }
        // 错误情况，)后面不是运算符
        if (/\)[^\+\-\*\/\)]/.test(string)) {
          return false;
        }
        // **错误情况最后一个字符是**+-*/
        if (/\*[\+\-\*\/]$/.test(string)) {
          return false;
        }
        return true;
      },
  
      rowDrop() {
        this.$nextTick(() => {
          let xTable = this.$refs.xTable;
          this.sortable = Sortable.create(
            xTable.$el.querySelector(".body--wrapper>.vxe-table--body tbody"),
            {
              handle: ".vxe-body--row",
              animation: 150,
              onEnd: ({ newIndex, oldIndex }) => {
                // 拖拽后回调
                /*
                  常规想法
                  此方法数组处理正常，但表格渲染顺序有问题
                  */
                // let currRow = this.tableData.splice(oldIndex, 1)[0];
                // this.tableData.splice(newIndex, 0, currRow);
  
                // 解决方案
                this.tableData.splice(
                  newIndex,
                  0,
                  this.tableData.splice(oldIndex, 1)[0]
                );
                var newArray = this.tableData.slice(0);
                this.tableData = [];
                this.$nextTick(function () {
                  this.tableData = newArray;
                });
              },
            }
          );
        });
      },
  
      // 添加成功或者编辑成功，回调方法
      handleGroupAddSuccess(e) {
        const { type, data } = e;
        // 这个 type 你到时候可以用来干嘛用，现在我不做任何作用，只是给你暴露出来，可能你会用到
        const list = this.tagGroups;
        if (Array.isArray(list)) {
          let index = list.findIndex((f) => f === data);
          this.handleGroupClick(data, index < 0 ? 0 : index);
        }
      },
    },
  };
  </script>
  <style scoped>
  .consult {
    width: 100%;
    height: 100%;
    background-color: #ffffff;
  }
  
  .tagGroup ul {
    list-style: none;
  }
  
  .tagGroup ul li {
    padding: 20px;
    border-bottom: 1px solid #eee;
  }
  .active {
    /* background: #ecf5ff;
    color: #409eff; */
    background: #cfe5fc;
    color: #000;
  }
  >>> .el-card__header {
    background: linear-gradient(180deg, #fff, #ededed);
  }
  >>> .el-card__body {
    padding: 0;
  }
  </style>